<template>
	<div id="cpn-table-field">
		<el-table @current-change="currentChange" :highlight-current-row="highlightCurrentRow" v-loading="loading"
			ref="tableRef" v-bind="$attrs" :default-sort="defaultSort" @sort-change="sortChange" :row-key="rowKey"
			:tree-props="treeProps" @selection-change="handleSelectionChange" @select="handleSelect"
			@row-click="handleRowClick" @select-all="handleSelectAll" :height="height" :stripe="stripe" :data="tableData"
			class="borderR">
			<slot></slot>
		</el-table>
		<!-- 分页 begin-->
		<el-pagination :layout="pageLayout" v-show="isShowPagination" @size-change="limitClick" @current-change="pageClick"
			:total="total" :current-page="defaultPage" :page-size="defaultPageSize" :page-sizes="pageSizes" />
		<!-- 分页 end-->
	</div>
</template>

<script setup lang='ts'>
import { ref, reactive, onMounted, defineExpose } from 'vue'
import baseService from "@/service/baseService"
import http from "@/utils/http"
type DefaultConfig = {
	url: string,
	rootProperty: string,
	data: object,
	params?: object,
	method?: string
}
let tableData = ref<Array<any>>([])
let loading = ref<boolean>(false)
let total = ref<number>(0)
let defaultPageSize = ref<number>(10)
let defaultPage = ref<number>(1)
let data = ref<Array<any>>([])
let defaultConfig = ref<DefaultConfig>({
	url: '',
	rootProperty: 'data',
	data: {},
	method: 'get'
})
let selection = ref<Array<any>>([])

interface TableProps {
	highlightCurrentRow?: boolean,
	// 默认的排序列的 prop 和顺序。它的prop属性指定默认的排序的列，order指定默认排序的顺序
	defaultSort?: { prop: string, order: string },
	rowKey?: string,
	treeProps?: object,
	// 表格高度
	height?: string | number,
	// 隔行换色
	stripe?: boolean,
	staticData?: Array<any>,
	config: {
		url: string,
		rootProperty: string,
		data: object
	},
	totalProperty?: string,
	showPagination?: boolean,
	pageType?: string,
	pageSize?: number,
	pageSizes?: Array<number>,
	pageField?: string,
	pageSizeField?: string,
	loadMask?: boolean,
	pageLayout?: string,
	isShowPagination?: boolean,
	total?: number,
}


const props = withDefaults(defineProps<TableProps>(), {
	highlightCurrentRow: false,
	height: 'auto',
	stripe: false,
	totalProperty: 'total',
	showPagination: true,
	pageType: 'number',
	pageSize: 10,
	pageSizes: () => [10, 20, 30, 40, 50, 100],
	pageField: 'page',
	pageSizeField: 'limit',
	loadMask: false,
	isShowPagination: true,
	pageLayout: 'total,prev,pager,next,sizes,jumper',
	total: 0,
})
const emit = defineEmits<{
	(e: 'current-change', ...args: Array<number>): void,
	(e: 'tableTotal', ...args: Array<number>): void,
	(e: 'tableData', ...args: Array<any>): void,
	(e: 'resData', ...args: Array<number>): void,
	(e: 'sort-change', data: { column: any, prop: string, order: any }): void,
	(e: 'selection-change', newSelection: any[]): void,
	<T = any>(e: 'select', newSelection: T[], row: T): void,
	(e: 'row-click', row: any): void,
	(e: 'select-all', newSelection: any[]): void,
	(e: 'pageChange', value: number): void,
	(e: 'limitChange', value: number): void,
}>()
const tableRef = ref()

/**
 * 根据下标修改data里面的值
*/
const set = (index: number, record: any) => {
	tableData.value[index] = record
}

const currentChange = (currentRow: number, oldCurrentRow: number) => {
	emit('current-change', currentRow, oldCurrentRow)
}

// 清空表格选中行
const clearSelection = () => {
	tableRef.value.clearSelection()
}

const loadData = (isReload: boolean = false, isSort: boolean = false) => {
	// 如果是静态挡板数据不发请求
	if (!props.config && props.staticData) {
		if (isSort === true) {
			tableData.value = props.staticData
		} else {
			success(props.staticData)
		}
		return
	}
	// 重置查询
	if (isReload === true) {
		reloadData()
	}
	// 处理data
	setConfig()
	// console.log('最新请求参数====', defaultConfig.value)
	// 发送请求
	doRequest(defaultConfig.value)
}
// 发送请求
const doRequest = (config: DefaultConfig) => {
	// 开启等待层
	if (props.loadMask) {
		loading.value = true
	}
	console.log('请求参数====', config)
	http(config).then(res => {
		data.value = res.data as Array<any>
		success(res.data)
	}).catch(() => {
		loading.value = false
	})
}
// 设置最新请求
const setConfig = () => {
	// 合并请求参数
	defaultConfig.value = Object.assign(defaultConfig.value, props.config)
	// 如果配置了分页
	if (props.showPagination === true) {
		// 设置分页信息
		(defaultConfig.value.data as any)[props.pageField] =
			props.pageType === 'string' ? defaultPage.value + '' : defaultPage.value;
		// 设置分页大小
		(defaultConfig.value.data as any)[props.pageSizeField] =
			props.pageType === 'string' ? defaultPageSize.value + '' : defaultPageSize.value
	}
	if (defaultConfig.value.method === 'get') {
		defaultConfig.value.params = defaultConfig.value.data
	}
}
// 重新查询
const reloadData = () => {
	defaultPage.value = 1
}
const success = (data: any) => {
	loading.value = false
	console.log('data===', data)
	//
	total.value = Number(data[props.totalProperty]) || data?.data?.total || 0
	console.log('total.value === ', total.value)
	// 取根集合
	let rootProperty = defaultConfig.value.rootProperty
	let tData = []
	// 处理
	if (rootProperty) {
		rootProperty.split('.').forEach((property) => {
			if (data) {
				data = data[property]
			}
		})
		tData = data
	}
	tableData.value = tData
	console.log('tableData', tableData.value)
	// 返回事件
	emit('tableTotal', total.value)
	emit('tableData', tableData.value)
	emit('resData', data)
}
const sortChange = (data: { column: any, prop: string, order: any }) => {
	emit('sort-change', data)
}

const toggleRowSelection = (row: any, selected: boolean) => {
	tableRef.value.toggleRowSelection(row, selected)
}
const handleSelectionChange = (newSelection: any[]) => {
	emit('selection-change', newSelection)
}
const handleSelect = <T = any>(newSelection: T[], row: T) => {
	selection.value = newSelection
	emit('select', newSelection, row)
}
const handleRowClick = (row: any, column: any, event: Event) => {
	emit('row-click', row)
}
const handleSelectAll = (newSelection: any[]) => {
	selection.value = newSelection
	emit('select-all', newSelection)
}
const pageClick = (value: number) => {
	emit('pageChange', value)
	defaultPage.value = value
	loadData()
}
const limitClick = (value: number) => {
	emit('limitChange', value)
	defaultPage.value = 1
	defaultPageSize.value = value
	loadData()
}

defineExpose({
	loadData
})

</script>

<style lang='scss' scoped></style>